<template>
  <ElRow justify="space-between">
    <ElForm :disabled="loading" inline>
      <ElFormItem v-for="item in condition" :label="item.label">
        <ElInput
          v-if="item.condition && item.condition === 'input'"
          clearable
          v-model:model-value="conditionValue[item.key]"
          v-bind="item.condition && item.conditionConfig"
        ></ElInput>
        <ElInputNumber
          v-if="item.condition && item.condition === 'input-number'"
          clearable
          v-model:model-value="conditionValue[item.key]"
          v-bind="item.condition && item.conditionConfig"
        ></ElInputNumber>
        <ElSelect
          style="min-width: 200px"
          v-if="item.condition && item.condition === 'select'"
          v-model:model-value="conditionValue[item.key]"
          clearable
        >
          <ElOption
            v-for="option in item.conditionConfig"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          ></ElOption
        ></ElSelect>
      </ElFormItem>
    </ElForm>
    <ElRow>
      <ElButton
        v-if="condition.length > 0"
        type="primary"
        :disabled="loading"
        @click="
          () => {
            page = 1;
            handleRefresh();
          }
        "
        style="margin-bottom: 20px"
      >
        查询
      </ElButton>
      <ElButton
        type="primary"
        :disabled="loading"
        @click="handleRefresh"
        style="margin-bottom: 20px"
      >
        刷新
      </ElButton>
    </ElRow>
  </ElRow>
  <ElSpace wrap v-if="$slots.header" style="margin-bottom: 20px">
    <ElForm :disabled="loading">
      <slot name="header"></slot>
    </ElForm>
  </ElSpace>
  <ElTable
    v-loading="loading"
    stripe
    border
    :data="data"
    style="margin-bottom: 20px"
    @selection-change="handleSelectionChange"
  >
    <ElTableColumn
      v-if="isSelection"
      :selectable="getIsSelecTable"
      type="selection"
      label="选择"
      fixed="left"
      :width="70"
      align="center"
    ></ElTableColumn>
    <ElTableColumn
      type="index"
      label="序号"
      fixed="left"
      :width="70"
      align="center"
    ></ElTableColumn>
    <ElTableColumn
      label="ID"
      align="center"
      width="120"
      prop="id"
    ></ElTableColumn>
    <ElTableColumn
      :label="isCreateTime"
      align="center"
      width="172"
      prop="createTime"
      v-if="isCreateTime"
    >
      <template #default="scope">
        {{ dayjs(scope.row.createTime).format("YYYY-MM-DD HH:mm:ss") }}
      </template>
    </ElTableColumn>
    <ElTableColumn
      :label="isUpdateTime"
      align="center"
      width="172"
      prop="updateTime"
      v-if="isUpdateTime"
    >
      <template #default="scope">
        {{ dayjs(scope.row.updateTime).format("YYYY-MM-DD HH:mm:ss") }}
      </template>
    </ElTableColumn>
    <ElTableColumn
      align="center"
      v-for="item in column"
      :label="item.label"
      :width="item.width"
      :minWidth="item.minWidth"
      :prop="item.key"
      :show-overflow-tooltip="item.render && item.render === 'text'"
      :fixed="item.fixed"
    >
      <template #default="scope" v-if="item.render && item.render !== 'text'">
        <slot
          v-if="item.render === 'slot'"
          :name="item.key"
          :row="scope.row"
          :index="scope.$index"
        ></slot>
        <ElRow justify="center" v-else-if="item.render === 'image'">
          <viewImage
            :src="scope.row[item.key]"
            :width="
              item.renderConfig ? item.renderConfig.width + 'px' : '100px'
            "
            :height="
              item.renderConfig ? item.renderConfig.height + 'px' : '100px'
            "
            :previewList="[scope.row[item.key]]"
          ></viewImage>
        </ElRow>
        <span v-else-if="item.render === 'select'">
          {{
            (
              (item.renderConfig &&
                item.renderConfig.find(
                  (e: any) => e.value === scope.row[item.key]
                )) || { label: "异常" }
            ).label
          }}
        </span>
        <span v-else-if="item.render === 'selects'">
          {{
            scope.row[item.key]
              .map(
                (key: any) =>
                  (
                    (item.renderConfig &&
                      item.renderConfig.find((e: any) => e.value === key)) || {
                      label: "异常",
                    }
                  ).label
              )
              .join(",")
          }}
        </span>
        <span v-else-if="item.render === 'montage'">
          {{
            ((item.renderConfig && item.renderConfig.key) || [])
              .map((key: string) => scope.row[key])
              .join((item.renderConfig && item.renderConfig.connect) || "")
          }}
        </span>
        <span v-else-if="item.render === 'time'">
          {{
            dayjs(scope.row[item.key]).format(
              item.renderConfig?.format || "YYYY-MM-DD HH:mm:ss"
            )
          }}
        </span>
        <ElTooltip
          v-else-if="item.render === 'link'"
          :content="scope.row[item.key]"
        >
          <ElText
            truncated
            type="primary"
            :href="scope.row[item.key]"
            tag="a"
            class="el-link"
            target="_black"
          >
            {{ scope.row[item.key] }}
          </ElText>
        </ElTooltip>
        <span v-else-if="item.render === 'formatter'">
          {{ item.renderConfig && item.renderConfig.formatter(scope) }}
        </span>
        <span v-else-if="item.render === 'money'">
          {{ Number(scope.row[item.key] || 0).toFixed(2) }}
        </span>
        <slot
          v-else-if="item.render === 'slot'"
          :name="item.key"
          v-bind="scope"
        ></slot>
        <span v-else>未知</span>
      </template>
    </ElTableColumn>
    <ElTableColumn
      label="操作"
      fixed="right"
      align="center"
      v-if="isOperation"
      :width="operationWidth"
    >
      <template #default="scope">
        <slot name="operation" :row="scope.row" :index="scope.index"> </slot>
        <ElButton
          type="info"
          v-if="clickEdit"
          @click="clickEdit && clickEdit(scope.row, scope.index)"
          size="default"
        >
          编辑
        </ElButton>
        <ElButton
          type="warning"
          v-if="clickDetail"
          @click="clickDetail && clickDetail(scope.row, scope.index)"
          size="default"
        >
          详情
        </ElButton>
        <ElButton
          type="danger"
          v-if="apiRemove"
          @click="handleRemove(scope.row.id)"
          size="default"
        >
          删除
        </ElButton>
      </template>
    </ElTableColumn>
  </ElTable>
  <ElRow justify="center" style="margin-bottom: 20px">
    <ElPagination
      :disabled="loading"
      v-model:current-page="page"
      v-model:page-size="pageSize"
      :pager-count="5"
      background
      layout="sizes, total, prev, pager, next, jumper"
      :total="total"
      @size-change="handleRefresh"
      @current-change="handleRefresh"
      @prev-click="handleRefresh"
      @next-click="handleRefresh"
    ></ElPagination>
  </ElRow>
</template>

<script setup lang="ts">
import type { PropType } from "vue";
import { ref, reactive, computed, onMounted } from "vue";
import {
  dayjs,
  ElRow,
  ElForm,
  ElFormItem,
  ElInput,
  ElInputNumber,
  ElSelect,
  ElOption,
  ElButton,
  ElSpace,
  ElTable,
  ElTableColumn,
  ElTooltip,
  ElText,
  ElPagination,
  ElMessageBox,
  ElMessage,
} from "element-plus";
import viewImage from "@/components/image.vue";
import ajax from "@/ajax";
const props = defineProps({
  option: {
    type: Array as PropType<
      {
        label: string;
        key: string;
        width?: number | string;
        minWidth?: number | string;
        fixed?: string | boolean;
        render?:
          | "text"
          | "slot"
          | "select"
          | "selects"
          | "image"
          | "montage"
          | "time"
          | "link"
          | "money"
          | "formatter"
          | "slot";
        renderConfig?: { [key: string]: any };
        condition?: "input" | "input-number" | "select";
        conditionConfig?: { [key: string]: any };
      }[]
    >,
    default: [],
  },
  clickEdit: {
    type: Function as PropType<(row: any, index: number) => void>,
  },
  clickDetail: {
    type: Function as PropType<(row: any, index: number) => void>,
  },
  apiList: {
    type: String,
    default: "",
  },
  apiListParameter: {
    type: Object,
    default() {
      return {};
    },
  },
  apiRemove: {
    type: String,
    default: "",
  },
  isSelection: {
    type: Boolean,
    default: false,
  },
  getIsSelecTable: {
    type: Function as PropType<(row: any, index: number) => boolean>,
  },
  isOperation: {
    type: Boolean,
    default: false,
  },
  operationWidth: {
    type: String,
    default: "200px",
  },
  isCreateTime: {
    type: String,
    default: "创建时间",
  },
  isUpdateTime: {
    type: String,
    default: "更新时间",
  },
  formatterList: {
    type: Function as PropType<(list: any[]) => any[]>,
  },
});
const loading = ref<boolean>(false);
const page = ref<number>(1);
const pageSize = ref<number>(10);
const total = ref<number>(0);
const data = reactive<any[]>([]);

const column = computed(function () {
  return props.option.filter((e) => e.render);
});

const conditionValue = ref<{ [key: string]: any }>({});
const condition = computed(function () {
  return props.option.filter((e) => e.condition);
});

const multipleSelection = ref([]);
const handleSelectionChange = function (val: any) {
  multipleSelection.value = val;
};

const handleRefresh = function () {
  if (!props.apiList) {
    return ElMessage.error("请求地址不存在");
  }
  loading.value = true;
  const parm = Object.assign(
    {
      "orders[0].asc": false,
      "orders[0].column": "create_time",
    },
    conditionValue.value,
    {
      current: page.value,
      size: pageSize.value,
    },
    props.apiListParameter
  );
  ajax
    .xhr(
      props.apiList +
        "?" +
        encodeURI(
          Object.keys(parm)
            .map((key) => `${key}=${parm[key]}`)
            .filter((e) => e.indexOf("undefined") === -1)
            .join("&")
        ),
      "get"
    )
    .then(function (res) {
      loading.value = false;
      if (res.code !== 200) {
        ElMessage.error(res.message);
        return;
      }
      page.value = res.data.current;
      pageSize.value = res.data.size;
      total.value = res.data.total;
      data.splice(
        0,
        data.length,
        ...(typeof props.formatterList === "function"
          ? props.formatterList(res.data.records)
          : res.data.records)
      );
    });
};
onMounted(handleRefresh);

const handleRemove = function (id: string) {
  ElMessageBox.confirm("你将要删除该数据，是否继续?", "Warning", {
    confirmButtonText: "取消",
    cancelButtonText: "继续",
    type: "warning",
  })
    .then(function () {})
    .catch(() => {
      loading.value = true;
      ajax.xhr(props.apiRemove + "/" + id, "delete").then(function (res) {
        loading.value = false;
        if (res.code !== 200) {
          ElMessage.error(res.message);
          return;
        }
        ElMessage.success("删除成功");
        handleRefresh();
      });
    });
};

defineExpose({
  handleRefresh,
  getSelectList<T = any>(): T[] {
    return multipleSelection.value;
  },
});
</script>

<style lang="scss" scoped></style>
